package com.atguigu.study.base.rwlock;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * @Author 快点干早点散
 * @Create 2025/4/25 18:24
 * Description:
 *  *  * 写线程首先获取写锁，更新数据，然后将锁降级为读锁。读线程在获取读锁后读取数据。
 *  *  * 这个过程演示了锁降级的概念，允许多个线程在持有读锁的情况下同时访问数据，
 *  *  * 提高了并发性能。`
 *  *  * 请注意，在锁降级期间，我们要确保数据的一致性，即在降级为读锁之前和之后都可以正确读取数据。
 *  *  * 这是锁降级的关键部分。（先获取读锁，再释放写锁）`
 */
public class LockDowngradingDemo {
    Map<String, String> map = new HashMap<>();
    private ReadWriteLock lock = new ReentrantReadWriteLock();

    public void updata(String key, String value) {
        lock.writeLock().lock();
        try {
            System.out.println(Thread.currentThread().getName() + "正在写入");
            map.put(key, value);
            System.out.println(Thread.currentThread().getName() + "写入成功");
            lock.readLock().lock();
        } finally {
            try {
                System.out.println(Thread.currentThread().getName() + "正在读取");
                String s = map.get(value);
                System.out.println(Thread.currentThread().getName() + "读取成功" + s);
            } finally {
                lock.readLock().unlock();
            }
            lock.writeLock().unlock();
        }
    }

    public void rade(String value) {
        lock.readLock().lock();
        try {
            System.out.println(Thread.currentThread().getName() + "正在读取");
            String s = map.get(value);
            System.out.println(Thread.currentThread().getName() + "读取成功" + s);
        }finally {
            lock.readLock().unlock();
        }
    }

    public static void main(String[] args) {
        LockDowngradingDemo lockDowngradingDemo = new LockDowngradingDemo();
        for (int i = 0; i < 5; i++) {
            int finalI=i;
            new Thread(() -> {
                lockDowngradingDemo.updata(finalI+"",finalI+"");
            },String.valueOf(i)).start();
        }

    }
}
